package com.free.ext.quartz;

import com.free.exception.SystemRuntimeException;
import com.free.ext.quartz.model.TaskStatusEnum;
import com.free.ext.quartz.tasker.Tasker;
import com.free.utils.DateUtils;
import org.quartz.*;

import java.util.Date;

/**
 * <p>
 * 功能概述: 
 * </p>
 * <p>
 * 功能详述: 
 * </p>
 */
public class TaskContainer extends Container
{

    /*========================================================================*
     *                         Public Fields (公共属性)                                                                
     *========================================================================*/

    /*========================================================================*
     *                         Private Fields (私有属性)                                                                
     *========================================================================*/

    private static final TaskContainer _instance = new TaskContainer();
    
    /*========================================================================*
     *                         Construct Methods (构造方法) 
     *========================================================================*/

    private TaskContainer()
    {
        super();
    }
    
    /*========================================================================*
     *                         Public Methods (公有方法)                                                                   
     *========================================================================*/
    public static TaskContainer instance()
    {
        return _instance;
    }
    
    public  <T extends Tasker> void add(T task)
    {
        if(!checkTask(task)) 
            return;
        try
        {
            Scheduler scheduler = scheduler();
            TriggerKey triggerKey = TriggerKey.triggerKey(task.getTaskNm(), task.getGroupNm());
            if(isTaskExists(task.getGroupNm(),task.getTaskNm()))
            {
                // Trigger已存在，那么更新相应的定时设置
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(task.getCronExperssion());
                CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
                scheduler.rescheduleJob(triggerKey, trigger);
                addTask(task);
            }
            else
            {
                Class<? extends Job> jobType = getJobType(task.getIsConcurrent());
                // 创建任务详情
                JobDetail jobDetail = JobBuilder.newJob(jobType).withIdentity(task.getTaskNm(), task.getGroupNm()).build();
                // 任务数据
                jobDetail.getJobDataMap().put("detail", task);
                // 创建trigger
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(task.getCronExperssion());
                CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
                
                // 运行任务
                scheduler.scheduleJob(jobDetail, trigger);
                addTask(task);
            }
        }
        catch(Throwable t)
        {
            throw new SystemRuntimeException("添加定时任务" ,t);
        }
    }

    public  <T extends Tasker> void add(T task, Date settingDate, Integer seconds)
    {
        if(!checkTask(task))
            return;
        try
        {
            Scheduler scheduler = scheduler();
            TriggerKey triggerKey = TriggerKey.triggerKey(task.getTaskNm(), task.getGroupNm());
            if(isTaskExists(task.getGroupNm(),task.getTaskNm()))
            {
                // Trigger已存在，那么更新相应的定时设置
                SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(seconds).repeatForever();
                SimpleTrigger trigger = TriggerBuilder.newTrigger().startAt(settingDate).withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
                scheduler.rescheduleJob(triggerKey, trigger);
                addTask(task);
            }
            else
            {
                Class<? extends Job> jobType = getJobType(task.getIsConcurrent());
                // 创建任务详情
                JobDetail jobDetail = JobBuilder.newJob(jobType).withIdentity(task.getTaskNm(), task.getGroupNm()).build();
                // 任务数据
                jobDetail.getJobDataMap().put("detail", task);
                // 创建trigger
                SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(seconds).repeatForever();
                SimpleTrigger trigger = TriggerBuilder.newTrigger().startAt(settingDate).withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
                // 运行任务
                scheduler.scheduleJob(jobDetail, trigger);
                addTask(task);
            }
        }
        catch(Throwable t)
        {
            throw new SystemRuntimeException("添加定时任务" ,t);
        }
    }
    
    public void pause(String groupNm, String taskNm)
    {
        try
        {
            if(pauseTask(groupNm, taskNm))
            {
                JobKey jobKey = JobKey.jobKey(taskNm,groupNm);
                scheduler().pauseJob(jobKey);
                updateTaskStatus(groupNm, taskNm, TaskStatusEnum.PAUSE);
            }
        }
        catch (Throwable e)
        {
            throw new SystemRuntimeException("暂停定时任务",e);
        }
    }
    
    /**
     * 
     * @param groupNm
     * @param taskNm
     * @param isForce
     */
    public void pauseForce(String groupNm, String taskNm, boolean isForce)
    {
        try
        {
            if(pauseTaskForce(groupNm, taskNm,isForce))
            {
                JobKey jobKey = JobKey.jobKey(taskNm,groupNm);
                scheduler().pauseJob(jobKey);
                updateTaskStatus(groupNm, taskNm, TaskStatusEnum.PAUSE);
            }
        }
        catch (Throwable e)
        {
            throw new SystemRuntimeException("强制暂停 定时任务",e);
        }
    }
    
    /**
     * 恢复执行
     * @param groupNm
     * @param taskNm
     */
    public void resume(String groupNm, String taskNm)
    {
        try
        {
            if(canResume(groupNm,taskNm))
            {
                JobKey jobKey = JobKey.jobKey(taskNm, groupNm);
                Scheduler schduler =  scheduler();
                schduler.resumeJob(jobKey);
                updateTaskStatus(groupNm, taskNm, TaskStatusEnum.FREE);
            }
        }
        catch (Throwable e)
        {
            throw new SystemRuntimeException("恢复 定时任务",e);
        }
    }
    
    /**
     * 立即执行
     * @param groupNm
     * @param taskNm
     */
    public void runImmediately(String groupNm, String taskNm)
    {
        try
        {
            if(canRunNow(groupNm, taskNm))
            {
                JobKey jobKey = JobKey.jobKey(taskNm, groupNm);
                scheduler().triggerJob(jobKey);
            }
        }
        catch (SchedulerException e)
        {
            throw new SystemRuntimeException("立即恢复 定时任务",e);
        }
    }
    /*========================================================================*
     *                         Private Methods (私有方法)                                                                   
     *========================================================================*/
}

